#include "mstar_tv.h"

MSTAR_TV::MSTAR_TV()
{
     count_dtvb=0;
     count_dtvc=0;

     old_cou_dtvb=0;
     old_cou_dtvc=0;

     count_atv=0;
     empty=0;
     read_atv=false;
     mstar_atv=NULL;
     mstar_dtv_data=NULL;

}





uint MSTAR_TV::Get_DTV_Count()
{

    return count_dtvb+count_dtvc;
}
void MSTAR_TV::Read_ATV()
{
     if(!mstar_atv)
     {
      mstar_atv=(MSTAR_ATV_DATA*)malloc(STRUCT_LEN_MS_A);
      if(!mstar_atv)
      {
           qDebug("in MSTAR_TV,mstar_atv is NULL,and malloc also error");
           return ;
      }
     }else
     {
        memset(mstar_atv,0,STRUCT_LEN_MS_A);
     }

     FILE *fp=fopen("database/atv_cmdb.bin","rb");
      if(!fp)
      {
               qDebug("open  file atv error");
           return ;
      }

      uchar pBuf[FILE_LEN_MS_A];
      fread(pBuf,1,FILE_LEN_MS_A,fp);

      memcpy(mstar_atv,pBuf,STRUCT_LEN_MS_A);
       //   qDebug(" %s",mstar_atv->ATVProgramData[0].ui_sName);
          fclose(fp);
          read_atv=true;
          Count_ATV();
}
//Read File until Channel Number as 0.the data after  0 Channel Number as invalid data.
uint  MSTAR_TV::Read_DTV_Bin(const char*dtv_file)
{
     //mstar_dtv.clear();
     uint tmp_count=0;
     if(dtv_file==NULL)
     {
      qDebug("dtv_file is Empty");
          return 1;
     }
     FILE *fp=fopen(dtv_file,"rb+");
     if(!fp)
     {
      qDebug("open file dtv error");
          return 0;
     }



  while(!feof(fp))
     {
      char pBuf[FILE_LEN_MS_D];
      fseek(fp,MSTAR_DTV_BIN_HEAD_LEN+FILE_LEN_MS_D*tmp_count,SEEK_SET);
      fread(pBuf,1,FILE_LEN_MS_D,fp);

          mstar_dtv_data=(MSTAR_DTV_DATA*)malloc(STRUCT_LEN_MS_D);
      if(!mstar_dtv_data)
      {
           qDebug("IN MSTAR_TV::READ_DTV_BIN  malloc error");
               return 0;
      }
     memset(mstar_dtv_data,0,STRUCT_LEN_MS_D);
     memcpy(mstar_dtv_data,pBuf,STRUCT_LEN_MS_D);
         //qDebug("%s",mstar_dtv_data->ui_ServiceName);
     if(mstar_dtv_data->ui2_Number<=0)
       {
         break;
      }
      mstar_dtv.append(mstar_dtv_data);
       //  qDebug("%d",mstar_dtv.at(tmp_count)->ui2_Number);
       tmp_count++;

     }
  qDebug("In MSTAR_TV::Read_DTV:%d",mstar_dtv.size());
  fclose(fp);
return tmp_count;
}


void MSTAR_TV::Read_DTV()
{
     const char * dtvb_name("database/dtv_cmdb_0.bin");
     count_dtvb=Read_DTV_Bin(dtvb_name);
     old_cou_dtvb=count_dtvb;

     const char *dtvc_name="database/dtv_cmdb_1.bin";
     count_dtvc= Read_DTV_Bin(dtvc_name);
     old_cou_dtvc=count_dtvc;
}


void  MSTAR_TV::Write_ATV()
{
     const char* file_name="database/atv_cmdb.bin";
     FILE *fp=fopen(file_name,"wb+");
     if(!fp)
     {
      qDebug("in write_atv open atv file error");
      return ;
     }

     char *pBuf=new char[FILE_LEN_MS_A];

     if(!pBuf)
     {
      qDebug("IN MSTAR_TV::Write_TV mstar_atv_data is　NULL");
      return ;
     }
     memset(pBuf,0,FILE_LEN_MS_A);
     memcpy(pBuf,mstar_atv,STRUCT_LEN_MS_A);
     fwrite(pBuf,1,FILE_LEN_MS_A,fp);
     fflush(fp);
     fclose(fp);
//clear atv data in mstar_tv class
     delete pBuf;
     pBuf=NULL;
}

void MSTAR_TV::Copy_File(const char *src, const char *dst, const uint src_start, const uint dst_start,const uint length)
{
    FILE *fp_src=fopen(src,"rb+");


    if(!fp_src)
    {

        qDebug("In MSTAR_TV::Copy_File open file %s  failed\n",src);
        return ;
    }

    fseek(fp_src,src_start,SEEK_SET);


    uchar pBuf[length];
    memset(pBuf,0,length);
    fread(pBuf,1,length,fp_src);
    fclose(fp_src);

    FILE *fp_dst=fopen(dst,"wb+");
    if(!fp_dst)
    {
        qDebug("In MSTAR_TV::Copy_File open file %s failed\n",dst);
        return ;
    }
    if(dst_start>0)
        fseek(fp_dst,0,SEEK_END);//由于每个记录频道信息的结构体之间存在字节对齐的问题。比如，6个DTV数据，在文件写完是到1957B，而通过计算传来的是1960这个是默认处理字节对齐
    else
        fseek(fp_dst,dst_start,SEEK_SET);
    fwrite(pBuf,1,length,fp_dst);
    fflush(fp_dst);

    fclose(fp_dst);


}


void MSTAR_TV::Write_DTV_Bin(const char *file,const uint count,uint start)
{
     FILE *fp=fopen(file,"ab");
     if(!fp)
     {
      qDebug("in write_dtv_bin open file error");
      return ;
     }
     int i=start;
     for(;i<count;i++)
     {
         // fseek(fp,MSTAR_DTV_BIN_HEAD_LEN+i*FILE_LEN_MS_D,SEEK_SET);
      mstar_dtv_data=mstar_dtv.at(i);
      char pBuf[FILE_LEN_MS_D];
      memset(pBuf,0,FILE_LEN_MS_D);
      memcpy(pBuf,mstar_dtv_data,STRUCT_LEN_MS_D);
      fwrite(pBuf,1,FILE_LEN_MS_D,fp);
      fflush(fp);
     }
     fclose(fp);

}

 void MSTAR_TV::Write_DTV()
{

     const char * dtvb_name("database/cmdb_0_tmp.bin");
     char *src_b="database/dtv_cmdb_0.bin";


     FILE *fp=fopen(src_b,"rb");
     if(!fp)
     {
        qDebug("in MSTAR_TV::Write_DTV open file dtv_cmdb_0.bin error");
        return ;
     }
     //get file length
     long length=0;
     fseek(fp,0,SEEK_END);
     length=ftell(fp);


     fseek(fp,0,SEEK_SET);
     char pBuf1[MSTAR_DTV_BIN_HEAD_LEN];
     fread(pBuf1,1,MSTAR_DTV_BIN_HEAD_LEN,fp);

     FILE *newfp=fopen(dtvb_name,"wb+");
     if(!newfp)
     {
        qDebug("in MSTAR_TV::Write_DTV open file  %s error",dtvb_name);
        return;
     }
     fwrite(pBuf1,1,MSTAR_DTV_BIN_HEAD_LEN,newfp);
     fflush(newfp);
     fclose(newfp);


     Write_DTV_Bin(dtvb_name,count_dtvb,0);

     newfp=fopen(dtvb_name,"ab");
     if(!newfp)
     {
        qDebug("in MSTAR_TV::Write_DTV open file  %s error",dtvb_name);
        return;
     }

     //here fseek ,I use old_cou_dtvb just to avoid a bug when appearred as users del the last row datas in QList
     const int last_len1=length-(MSTAR_DTV_BIN_HEAD_LEN+FILE_LEN_MS_D*count_dtvb);//file offset start at 0
     if(last_len1>0)
     {
        fseek(fp,MSTAR_DTV_BIN_HEAD_LEN+FILE_LEN_MS_D*old_cou_dtvb,SEEK_SET);
        char pBuf2[last_len1];
        fread(pBuf2,1,last_len1,fp);
        fclose(fp);
        //fseek(newfp,0,SEEK_END);
        fseek(fp,MSTAR_DTV_BIN_HEAD_LEN+FILE_LEN_MS_D*old_cou_dtvb,SEEK_SET);
        fwrite(pBuf2,1,last_len1,newfp);
        fflush(newfp);
        fclose(newfp);

     }else
     {
        fclose(fp);
        fclose(newfp);
     }


     const char *dtvc_name="database/cmdb_1_tmp.bin";
     char *src_c="database/dtv_cmdb_1.bin";
    // Copy_File(src,dtvc_name,0,0,MSTAR_DTV_BIN_HEAD_LEN);

            fp=fopen(src_c,"rb+");
             if(!fp)
             {
                qDebug("in MSTAR_TV::Write_DTV open file dtv_cmdv_1.bin error");
                return ;
             }
             //get file length
             fseek(fp,0,SEEK_END);
             length=ftell(fp);

             fseek(fp,0,SEEK_SET);
             char pBuf3[MSTAR_DTV_BIN_HEAD_LEN+1];
             fread(pBuf3,1,MSTAR_DTV_BIN_HEAD_LEN,fp);
             newfp=fopen(dtvc_name,"wb+");
             if(!newfp)
             {
                qDebug("in MSTAR_TV::Write_DTV open file %s error",dtvc_name);
                return;
             }
             fwrite(pBuf3,1,MSTAR_DTV_BIN_HEAD_LEN,newfp);
             fflush(newfp);
             fclose(newfp);

             Write_DTV_Bin(dtvc_name,count_dtvc,count_dtvb);

             newfp=fopen(dtvc_name,"ab");
             if(!newfp)
             {
                qDebug("in MSTAR_TV::Write_DTV open file %s error",dtvc_name);
                return;
             }
             const int last_len2=length-(MSTAR_DTV_BIN_HEAD_LEN+FILE_LEN_MS_D*count_dtvc);
             if(last_len2>0)
             {
                fseek(fp,MSTAR_DTV_BIN_HEAD_LEN+FILE_LEN_MS_D*count_dtvc,SEEK_SET);
                char pBuf4[last_len2];
                fread(pBuf4,1,last_len2,fp);
                fclose(fp);
                fwrite(pBuf4,1,last_len2,newfp);
                fclose(newfp);
             }else
             {
                fclose(fp);
                fclose(newfp);
             }

  }

uint MSTAR_TV::Count_ATV()
{
   count_atv=256;
   return count_atv;
}


//set atv u_wPLL as 0,then the data be invalid.
void MSTAR_TV::Del_ATV_Row(int row)
{
   // mstar_atv->ui_lastPRNumber=0;
    //memset(mstar_atv->ui_ATVPRIndexTable,0,MAX_NUMBER_OF_ATV_PROGRAM);
    //memset(mstar_atv->ui_ATVPRTableMap,0,MAX_PRTableMAP);
    mstar_atv->ATVProgramData[row].ui2_wPLL=0;
    //ushort tmp[4]={0,0,0,0};
    //memcpy(mstar_atv->ATVProgramData[row].misc,tmp,4);
   // mstar_atv->ATVProgramData[row].misc.u_AFT=0;
   // mstar_atv->ATVProgramData[row].misc.u_AftOffset=0;
   // mstar_atv->ATVProgramData[row].misc.u_AudioMode=0;
   // mstar_atv->ATVProgramData[row].misc.u_AudioStandard=0;
   mstar_atv->ATVProgramData[row].misc.u_ChannelNumber=0;
   // mstar_atv->ATVProgramData[row].misc.u_Favorite=0;
    //memset(mstar_atv->ATVProgramData[row].ui_sName,0,MAX_STATION_NAME);
    //memset(mstar_atv->ATVProgramData[row].ui_ListPage,0,MAX_LISTPAGE_SIZE);
    mstar_atv->ATVProgramData[row].misc.u_Hide=1;
}
//remove the data form qList,del the row,the other datas will be OK
//in here ,wo need the dtv class can't mnodify
void MSTAR_TV::Del_DTV_Row(int row)
{
//    mstar_dtv_data=mstar_dtv.at(row);
    Q_ASSERT(row<mstar_dtv.size());
    mstar_dtv.removeAt(row);
   if(row<count_dtvb)
        count_dtvb--;
   else
       count_dtvc--;
}

void MSTAR_TV::Mod_ATV(int row,int col,QString value)
{
    switch(col)
    {
    case 0:

        mstar_atv->ATVProgramData[row].misc.u_ChannelNumber=value.toUShort();

        break;
    case 1:
        memcpy(mstar_atv->ATVProgramData[row].ui_sName,value.toStdString().c_str(),
               strlen(value.toStdString().c_str()));
        qDebug("%s",mstar_atv->ATVProgramData[row].ui_sName);
        break;
    case 2:
        break;
    case 3:
        mstar_atv->ATVProgramData[row].misc.u_Favorite=value.toUShort();
        break;
    case 4:
        mstar_atv->ATVProgramData[row].misc.u_Skip=value.toUShort();
        break;
    default:
            qDebug("in  MSTAR_TV::Mod_ATV para col error");
    }
}
//usually checksum very big,it will not below 0,but here is dangerous
void MSTAR_TV::Mod_Check(ushort num1, ushort num2)
{
    mstar_dtv_data->ui4_CheckSum+=num2;
    mstar_dtv_data->ui4_CheckSum-=num1;
}

void MSTAR_TV::Mod_DTV(int row, int col, QString value)
{
    //if(row>count_dtvb)
      //  mstar_dtv_data=mstar_dtv.at(row);
    mstar_dtv_data=mstar_dtv.at(row);
    switch(col)
    {
    case 0:

     Mod_Check(mstar_dtv_data->ui2_Number,(ushort)value.toUInt());
     mstar_dtv_data->ui2_Number=(ushort)value.toUInt();
        break;
    case 1:
    {
        string str=value.toStdString();
        const uint len=str.length();
        const uint length=strlen((const char *)mstar_dtv_data->ui_ServiceName);
        for(uint i=0;i<MAX_SERVICE_NAME;i++)
        {
            if(i<len)
            mstar_dtv_data->ui4_CheckSum+=str.at(i);
            if(i<length)
            mstar_dtv_data->ui4_CheckSum-=mstar_dtv_data->ui_ServiceName[i];
        }
        memset(mstar_dtv_data->ui_ServiceName,0,MAX_SERVICE_NAME);
        memcpy(mstar_dtv_data->ui_ServiceName,str.c_str(),
               strlen(str.c_str()));
        qDebug("%s",mstar_dtv_data->ui_ServiceName);
        break;
    }
    case 2://class暂时不可修改
        //Mod_Check(mstar_dtv_data->u_,(ushort)value.toUInt());
        //mstar_dtv_data->ui2_class=(ushort)value.toUInt();
       // break;
    case 3:
        Mod_Check((ushort)mstar_dtv_data->ui_Favorite,value.toUInt());
        mstar_dtv_data->ui_Favorite=value.toInt();
        break;
    case 4:
        Mod_Check(mstar_dtv_data->u_IsSkipped,(ushort)value.toUInt());
        mstar_dtv_data->u_IsSkipped=value.toStdString().at(0);//char类型
        break;
    default:
        qDebug("in  MATAR_TV::Mod_DTV para col eror");
    }

}


bool MSTAR_TV::Is_Empty()
{
    if(empty<=0)
        return true;
    else
        return false;

}
void MSTAR_TV::Clear()
{

    delete mstar_atv;
    mstar_atv=NULL;



    //qDeleteAll(mstar_dtv);
    for(int i=0;i<mstar_dtv.size();i++)
        free(mstar_dtv.at(i));
    //delete mstar_dtv_data;
    mstar_dtv_data=NULL;
    mstar_dtv.clear();
    read_atv=false;
    count_atv=0;
    count_dtvb=0;
    count_dtvc=0;
    old_cou_dtvb=0;
    old_cou_dtvc=0;
}

void MSTAR_TV::set_Empty(uint num)
{
    empty=num;
}

void MSTAR_TV::Empty_Add_One()
{
    empty++;
}

void MSTAR_TV::Empty_Dul_One()
{
    empty--;
}
